package com.ncmmall.mall.controller.business.order;

import com.feijin.commons.excel.ExcelExports;
import com.feijin.commons.lang.ArithUtils;
import com.feijin.commons.lang.Dates;
import com.feijin.commons.webs.Webs;
import com.ncmmall.domain.business.goods.Goods;
import com.ncmmall.domain.business.order.Order;
import com.ncmmall.domain.business.order.OrderDetail;
import com.ncmmall.domain.business.order.QOrder;
import com.ncmmall.domain.security.user.QWebUser;
import com.ncmmall.domain.security.user.WebUser;
import com.ncmmall.mall.params.PageParams;
import com.ncmmall.querychannel.QueryPage;
import com.ncmmall.querychannel.QueryPageRequest;
import com.ncmmall.querychannel.service.QueryChannelService;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 订单管理
 *
 * @author linxs
 * @date 2019-07-10 17:44
 */
@Controller
@RequestMapping(value = "/mall/order")
@Slf4j
public class OrderController {

    @Autowired
    private QueryChannelService queryChannelService;

    /**
     * 订单列表
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public String list(Model model, PageParams pageParams, Order order) {
        QueryPageRequest pageRequest = new QueryPageRequest().setPageNo(pageParams.getPageNo());
        Map<String, Object> params = new HashMap<>();
        String hql = builderSQL("select u from Order u where 1=1 ", params, order);
        QueryPage<Order> page = queryChannelService.findPage(hql, pageRequest.setParams(params), Order.class);
        List<WebUser> merchants = queryChannelService.findAll(QWebUser.webUser.role.name.eq("MERCHANT"), WebUser.class);

        double payAmount;
        double shoppingCardMoney;
        double refundAmount;
        int members;

        if (order.getMerchant() != null && order.getMerchant().getId() > 0) {
            payAmount = queryChannelService.selectSum("select ifnull(sum(o.price),0) from mall_order o where o.payStatus = 1 and o.merchant_id = :id ", ImmutableMap.of("id", order.getMerchant().getId()));
            shoppingCardMoney = queryChannelService.selectSum("select ifnull(sum(o.shoppingCardMoney),0) from mall_order o where o.payStatus = 1 and o.merchant_id = :id ", ImmutableMap.of("id", order.getMerchant().getId()));
            refundAmount = queryChannelService.selectSum("select ifnull(sum(o.price),0) from mall_order o where o.isAfterSale = 1 and o.merchant_id = :id ", ImmutableMap.of("id", order.getMerchant().getId()));
            members = queryChannelService.selectCount("select count(distinct(o.member_id)) from mall_order o where o.merchant_id = :id", ImmutableMap.of("id", order.getMerchant().getId()));

        } else {
            payAmount = queryChannelService.selectSum("select ifnull(sum(o.price),0) from mall_order o where o.payStatus = 1 ", new HashMap<>());
            shoppingCardMoney = queryChannelService.selectSum("select ifnull(sum(o.shoppingCardMoney),0) from mall_order o where o.payStatus = 1", Collections.emptyMap());
            refundAmount = queryChannelService.selectSum("select ifnull(sum(o.price),0) from mall_order o where o.isAfterSale = 1 ", new HashMap<>());
            members = queryChannelService.selectCount("select count(distinct(o.member_id)) from mall_order o", new HashMap<>());
        }

        payAmount = ArithUtils.add(payAmount, shoppingCardMoney);
        model.addAttribute("page", page).addAttribute("params", order).addAttribute("merchants", merchants).addAttribute("payAmount", payAmount).addAttribute("refundAmount", refundAmount).addAttribute("members", members);

        return "mall/order/list";
    }

    /**
     * 导出Excel
     */
    @RequestMapping(value = "/exports", method = RequestMethod.GET)
    private void exports(HttpServletRequest request, HttpServletResponse response, Order order) {
        Map<String, Object> params = Maps.newHashMap();
        String sql = "select u from Order u where 1=1 ";
        String hql = builderSQL(sql, params, order);

        List<Order> result = queryChannelService.findAll(hql, params, Order.class);
        for (Order item : result) {

            List<String> names = Lists.newArrayList();
            for (OrderDetail detail : item.getDetails()) {
                names.add(detail.getGoodsName());
            }

            item.setExpressCompany(Joiner.on("、").join(names));

        }

        Map<String, Object> data = ImmutableMap.of("result", result);
        ExcelExports document = new ExcelExports.Templates().formTemplate("orders.ftl").bind(data).store("orders.xls").build();

        try {
            document.generate();
            Webs.download(request, response, document.getFile(), "订单" + Dates.transDateToStr(new Date()) + ".xls");

        } catch (Exception e) {
            log.error("[导出异常]", e);
        }
    }


    /**
     * 查看详情
     */
    @RequestMapping(value = "/{id}/detail", method = RequestMethod.GET)
    private String detail(Model model, @PathVariable("id") long id) {

        Order order = queryChannelService.findOne(QOrder.order.id.eq(id), Order.class);

        List<Goods> giftGoodses = Lists.newArrayList();

        //赠品活动订单
        if (order.getMarketingType() == 1) {
            giftGoodses = queryChannelService.findAll("select g.goods from GiftGoods g where g.gift.id = :id ", ImmutableMap.of("id", order.getGiftActivity().getId()), Goods.class);
        }

        model.addAttribute("order", order);
        model.addAttribute("giftgoodses", giftGoodses);

        return "mall/order/detail";
    }

    /**
     * 查看详情
     */
    @RequestMapping(value = "/{id}/orderDetail", method = RequestMethod.GET)
    private String orderDetail(Model model, @PathVariable("id") String orderNo) {

        Order order = queryChannelService.findOne(QOrder.order.orderNo.eq(orderNo), Order.class);

        List<Goods> giftGoodses = Lists.newArrayList();

        //赠品活动订单
        if (order.getMarketingType() == 1) {
            giftGoodses = queryChannelService.findAll("select g.goods from GiftGoods g where g.gift.id = :id ", ImmutableMap.of("id", order.getGiftActivity().getId()), Goods.class);
        }

        model.addAttribute("order", order);
        model.addAttribute("giftgoodses", giftGoodses);

        return "mall/order/detail";
    }


    /**
     * 条件筛选
     */
    private String builderSQL(String sql, Map<String, Object> params, Order order) {

        if (order.getMerchant() != null && order.getMerchant().getId() > 0) {
            sql += " and u.merchant.id = :merchantId ";
            params.put("merchantId", order.getMerchant().getId());
        }

        if (order.getMember() != null && order.getMember().getId() > 0) {
            sql += " and u.member.id = :memberId ";
            params.put("memberId", order.getMember().getId());
        }

        if (order.getStatus() > 0) {
            sql += " and u.status = :status ";
            params.put("status", order.getStatus());
        }

        if (null != order.getMerchant() && order.getMerchant().getId() != 0) {
            sql += " and u.merchant.id = :mid ";
            params.put("mid", order.getMerchant().getId());
        }

        if (!Strings.isNullOrEmpty(order.getOrderNo())) {
            sql += " and u.orderNo like :orderno ";
            params.put("orderno", "%" + order.getOrderNo() + "%");
        }

        if (!Strings.isNullOrEmpty(order.getDeliveryMobile())) {
            sql += " and u.deliveryMobile like :deliverymobile ";
            params.put("deliverymobile", "%" + order.getDeliveryMobile() + "%");
        }

        if (!Strings.isNullOrEmpty(order.getDeliveryName())) {
            sql += " and u.deliveryName like :deliveryname ";
            params.put("deliveryname", "%" + order.getDeliveryName() + "%");
        }

        if (order.getPayMethod() > 0) {
            sql += " and u.payMethod = :paymethod ";
            params.put("paymethod", order.getPayMethod());
        }

        if (order.getPayStatus() > 0) {
            sql += " and u.payStatus = :pstatus ";
            params.put("pstatus", order.getPayStatus());
        }

        if (!Strings.isNullOrEmpty(order.getOrderByCreateTime())) {
            sql += " order by u.createTime " + order.getOrderByCreateTime();
        }

        if (!Strings.isNullOrEmpty(order.getOrderByPrice())) {
            sql += " order by u.price " + order.getOrderByPrice();
        }

        if (!sql.contains("order by")) {
            sql += " order by u.createTime desc ";
        }

        return sql;
    }

}
